package xyz.fivefaith.tool.mybatis.mapper;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;

import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.exceptions.TooManyResultsException;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;

/**
 * faith-BaseMapper
 *
 * @author zhaoanchi
 * @version 1.0
 * @since 2023-09-18 15:15
 */
public interface FaithBaseMapper<T> extends BaseMapper<T> {

    /**
     * 根据 ID 更新固定的那几个字段(但是不包含逻辑删除)
     *
     * @param entity 实体
     * @return 修改行数
     */
    int alwaysUpdateSomeColumnById(@Param(Constants.ENTITY) T entity);

    /**
     * 根据 whereEntity 条件，更新记录(但是不包含逻辑删除)
     *
     * @param entity 实体对象 (set 条件值,可以为 null)
     * @param updateWrapper 实体对象封装操作类（可以为 null,里面的 entity 用于生成 where 语句）
     * @return 修改行数
     */
    int alwaysUpdate(
            @Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper<T> updateWrapper);

    /**
     * 根据 ID 查询
     *
     * @param id 主键ID
     * @return entity
     */
    T alwaysSelectById(Serializable id);

    /**
     * 查询（根据ID 批量查询）
     *
     * @param idList 主键ID列表(不能为 null 以及 empty)
     * @return List::entity
     */
    List<T> alwaysSelectBatchIds(@Param(Constants.COLL) Collection<? extends Serializable> idList);

    /**
     * 根据 entity 条件，查询一条记录
     *
     * <p>查询一条记录，例如 qw.last("limit 1") 限制取一条记录, 注意：多条数据会报异常
     *
     * @param queryWrapper 实体对象封装操作类（可以为 null）
     * @return entity
     */
    default T alwaysSelectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper) {
        List<T> list = this.alwaysSelectList(queryWrapper);
        // 抄自 DefaultSqlSession#selectOne
        if (list.size() == 1) {
            return list.get(0);
        } else if (list.size() > 1) {
            throw new TooManyResultsException(
                    "Expected one api (or null) to be returned by selectOne(), but found: "
                            + list.size());
        } else {
            return null;
        }
    }

    /**
     * 根据 Wrapper 条件，查询总记录数
     *
     * @param queryWrapper 实体对象封装操作类（可以为 null）
     * @return 记录数
     */
    Long alwaysSelectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

    /**
     * 根据 entity 条件，查询全部记录
     *
     * @param queryWrapper 实体对象封装操作类（可以为 null）
     * @return List::entity
     */
    List<T> alwaysSelectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
}
